package com.diaohaiwen.framework.logging;

import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.diaohaiwen.common.log.BaseLogSend;
import com.diaohaiwen.common.obj.cache.RequestCache;
import com.diaohaiwen.common.log.LogProperties;
import com.diaohaiwen.common.obj.log.LogbackLog;
import com.diaohaiwen.common.constant.RequestConstant;
import jakarta.annotation.Resource;
import org.slf4j.MDC;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 刁海文
 * @desc
 * @since 2022/5/27 19:40
 */
@Component
public class GlobalLogbackEncoder extends PatternLayoutEncoder {


    @Resource
    LogProperties config;
    @Resource
    ApplicationContext context;

    @Resource
    BaseLogSend baseLogSend;
    @Override
    public byte[] encode(ILoggingEvent event) {
        // 放到缓存线程池内执行
        convertEventWithError(event);
        return super.encode(event);

    }


    private void convertEventWithError(ILoggingEvent event) {
        if (!config.isLogback()) {
            return;
        }

        // 获取源Msg替换结果-------------------------------------------
        String msg = StrUtil.format(event.getMessage(), event.getArgumentArray());
        LogbackLog logbackLog = new LogbackLog();
        logbackLog.setThreadName(event.getThreadName())
                .setLevel(event.getLevel().levelStr)
                .setTemplate(event.getMessage())
                .setMsg(StrUtil.replaceChars(msg, "\n\t\r", ""))
                .setLoggerName(event.getLoggerName())
                .setLoggerTime(LocalDateTime.now())
                .setRequestId(RequestCache.getThreadRequestId())
                .setLinkId(RequestCache.getThreadLinkId())
                .setApplicationName(SpringUtil.getApplicationName())
                .setIp(RequestCache.LOCAL_IP)
                .setLoginId(MDC.get(RequestConstant.LoginId))
                .setLoginName(MDC.get(RequestConstant.LoginName));
        // 尝试获取错误日志--------------------------------------------
        IThrowableProxy err = event.getThrowableProxy();
        if (err != null) {
            List<String> traces = new ArrayList<>();
            StackTraceElementProxy[] errTrack = err.getStackTraceElementProxyArray();
            for (StackTraceElementProxy element : errTrack) {
                if (element.getStackTraceElement().getClassName().startsWith("com.diaohaiwen")) {
                    traces.add(element.toString());
                }
            }
            logbackLog.setErrorClass(err.getClassName())
                    .setErrorMsg(err.getMessage())
                    .setErrorTraces(traces);
        }
        baseLogSend.executeLogback(logbackLog);
    }
}
